package t1;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class Server {
    //1.定义成员
    private Selector selector;
    private ByteBuffer buffer;
    private ServerSocketChannel ssChannel;
    private static final int PORT = 9999;
    public Server() {
        try {
            //选择器创建
            selector = selector.open();
            //通道获取
            ssChannel = ServerSocketChannel.open();
            //绑定端口
            ssChannel.socket().bind(new InetSocketAddress(PORT));
            //非阻塞通信模式
            ssChannel.configureBlocking(false);
            //通道注册到选择器上
            ssChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private void listen(){

            try {

                    while ((selector.select() > 0)) {
                        System.out.println("监听线程: " + Thread.currentThread().getName());
                        //把事件放到迭代器中，事件是Selectionkey          选择器选择事件，再选择迭代器
                        Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
                        while (keys.hasNext()) {//遍历事件
                            //提取事件
                            SelectionKey key = keys.next();
                            //判断事件类型
                            if (key.isAcceptable()) {//接入请求（写入）
                                //获取通道
                                SocketChannel sChannel = ssChannel.accept();
                                //非阻塞
                                sChannel.configureBlocking(false);
                                //注册选择器
                                sChannel.register(selector, SelectionKey.OP_READ);
                            } else if (key.isReadable()) {
                                readClientData(key);
                            }
                            keys.remove();
                        }
                    }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    private void readClientData(SelectionKey key) {
        SocketChannel sChannel = null;
        try{//sChannel自动关闭
            sChannel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = sChannel.read(buffer);
            if (count > 0) {
                buffer.flip();
                String msg = new String(buffer.array(), 0, count);
                System.out.println("接受了消息"+msg);
                sendMsgtoAllClient(msg,sChannel);
            }
        }catch (Exception e){
            try {
                System.out.println(sChannel.getRemoteAddress() + " 离线了..");
                //取消注册
                key.cancel();
                //关闭通道
                sChannel.close();
            }catch (IOException e2) {
                e2.printStackTrace();;
            }
        }
    }

    private void sendMsgtoAllClient(String msg, SocketChannel sChannel) throws IOException {
        System.out.println("开始转发消息，当前线程:"+Thread.currentThread().getName());
        for (SelectionKey key : selector.keys()) {
            Channel channel =  key.channel();
            //别发给自己
            if (channel instanceof SocketChannel && channel != sChannel) {
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
                ((SocketChannel)channel).write(buffer);
            }
        }
    }


    public static void main(String[] args) {
        //创建服务器
        Server server = new Server();
        //监听
        server.listen();

    }
}
